express = require('express');
const router = express.Router();
const rds = require('../rds');
const moment = require('moment');
const path = require('path');
const multer = require('multer');
const hbs = require('hbs');
const fs = require('fs');
const { permissions } = require('./trial-auth');

// 确保上传目录存在
const uploadDir = path.join(__dirname, '../public/uploads/trial');
if (!fs.existsSync(uploadDir)) {
    fs.mkdirSync(uploadDir, { recursive: true });
}

// 配置 multer，处理文件上传
const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, uploadDir);
    },
    filename: function (req, file, cb) {
        // 生成文件名：时间戳 + 随机数 + 原始扩展名
        const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
        const ext = path.extname(file.originalname);
        cb(null, 'subject-profile-' + uniqueSuffix + ext);
    }
});

const fileUpload = multer({
    storage: storage,
    limits: {
        fileSize: 5 * 1024 * 1024, // 限制文件大小为5MB
    },
    fileFilter: function (req, file, cb) {
        // 只接受图片文件
        if (!file.originalname.match(/\.(jpg|jpeg|png|gif)$/)) {
            return cb(new Error('只允许上传图片文件'));
        }
        cb(null, true);
    }
});

// 配置 multer，只解析表单字段，不处理文件
const upload = multer();

//模块中无需再注册view engine, 不支持-连接的文件名
hbs.registerPartials( path.join(__dirname, '../views/trial/partials'), {extname:'.hbs'} );

hbs.registerHelper('formatGender', function(gender) { return gender == 1 ? '男' : '女'; });
hbs.registerHelper('calculateAge', function(birthDate) {
    if (!birthDate) return 0;
    try {
        const birth = new Date(birthDate); const ageYears = (Date.now() - birth) / (3.15576e+10); // 简化时间计算
        return parseFloat(ageYears.toFixed(1));
    } catch (error) {
        console.error('计算年龄时出错:', error); return 0;
    }
});
hbs.registerHelper('groupByStatus', function(subjects) {
    const order = [3, 2, 1, 4, 5, 6, 9, 0]; // 定义状态的排列顺序
    const grouped = subjects.reduce((acc, subject) => {
        if (!acc[subject.status]) {
            acc[subject.status] = { status: subject.status, subjects: [] };
        }
        acc[subject.status].subjects.push(subject);
        return acc;
    }, {});
    return Object.values(grouped).sort((a, b) => order.indexOf(a.status) - order.indexOf(b.status));
});
hbs.registerHelper('within24H', function(createdAt) {
    const now = new Date();
    const created = new Date(createdAt);
    const hours = (now - created) / 36e5; // 转换为小时,不取绝对值
    return hours <= 24;
});

// 添加新的辅助函数
hbs.registerHelper('formatDate', function(date, format) {
    if (!date) return '';
    return moment(date).format(format);
});

hbs.registerHelper('now', function() {
    return new Date();
});

hbs.registerHelper('addDays', function(date, days) {
    if (!date) return '';
    return moment(date).add(days, 'days').toDate();
});

hbs.registerHelper('lt', function(a, b) {
    return a < b;
});

// 统一的试验系统权限检查中间件
function trialAuth(req, res, next) {

    const role = req.session.trialROLE || 'trial-subject';
    // 获取完整的路径，去除查询参数
    const fullPath = req.originalUrl.split('?')[0].replace('/apps/trial', '');
    const path = fullPath.endsWith('/') ? fullPath.slice(0, -1) : fullPath;

    // 检查用户角色是否有权限访问当前路径
    const allowedPaths = permissions[role];
    const hasPermission = allowedPaths && allowedPaths.some(allowedPath => {
        const regex = new RegExp(`^${allowedPath.replace(/:\w+/g, '[^/]+')}$`);
        return regex.test(path);
    });

    if (hasPermission) {
        next();
    } else {
        res.render('warn', {
            title: '临床研究支持',
            message: '访问受限',
            description: '您没有权限访问此页面',
            icon: 'weui-icon-warn weui-icon_msg'
        });
    }
}

// 在现有路由之前添加首页路由
router.get('/', trialAuth, async (req, res) => {
    const role = req.session.trialROLE || 'trial-subject';
    const userId = req.session.totemUID;
    const userFlag = `${role}#${userId}`;

    res.render('trial/index', {
        userFlag,
        role,
        menus: [
            ...(role !== 'trial-subject' ? [{
                name: '试验管理',
                url: '/apps/trial/admin/trials',
                icon: 'fas fa-tasks',
                description: '管理临床试验项目和随访计划'
            }] : []),
            {
                name: '我的试验',
                url: '/apps/trial/my/trials',
                icon: 'fas fa-microscope',
                description: '查看可参与的试验和随访记录'
            },
            {
                name: '量表评估',
                url: '/apps/scales/scales-dashboard',
                icon: 'fas fa-clipboard-list',
                description: '可使用的量表工具和评估记录'
            }
        ]
    });
});

// 管理端路由
router.get('/admin/trials', trialAuth, async (req, res) => {
    const [trials] = await rds.query(
        `SELECT t.*, u.real_name as principal_name
         FROM trials t
         LEFT JOIN eb_user u ON t.principal_id = u.uid
         ORDER BY t.created_at DESC`
    );

    res.render('trial/admin/trials', {
        trials: trials.map(t => ({
            ...t,
            trial_status_text: ['准备中', '进行中', '已完成', '已终止'][t.trial_status],
            recruit_status_text: ['未开放报名', '已开放报名', '招募进行中', '招募已结束'][t.recruit_status],
            start_date: moment(t.start_date).format('YYYY-MM-DD'),
            end_date: t.end_date ? moment(t.end_date).format('YYYY-MM-DD') : '-'
        })),
        userId: req.session.totemUID,
        role: req.session.trialROLE
    });
});

// 获取试验详情的路由
router.get('/admin/trials/:trialId', trialAuth, async (req, res) => {
    const { trialId } = req.params;
    const [[trial]] = await rds.query('SELECT * FROM trials WHERE id = ?', [trialId]);

    if (!trial) {
        return res.json({ success: false, message: '试验不存在' });
    }

    // 格式化日期
    trial.start_date = moment(trial.start_date).format('YYYY-MM-DD');
    trial.end_date = trial.end_date ? moment(trial.end_date).format('YYYY-MM-DD') : '';
    // 添加试验代码
    trial.trial_code = trial.trial_code || '';

    res.json({ success: true, trial });
});

// 更新试验信息
router.post('/admin/trials/:trialId', trialAuth, async (req, res) => {
    try {
        const { trialId } = req.params;
        const {
            trial_name, trial_status, recruit_status, trial_code, description, apply_tip, entry_tip, confirm_tip, track_tip, exit_tip,
            group_info_template, promotion_url, start_date, end_date, group_config
        } = req.body;

        await rds.query( `UPDATE trials
            SET trial_name = ?, trial_status =?, recruit_status = ?, trial_code = ?, description = ?, apply_tip = ?, entry_tip = ?, confirm_tip = ?,
                track_tip = ?, exit_tip = ?, group_info_template = ?, promotion_url = ?, start_date = ?, end_date = ?, group_config = ?  WHERE id = ?`,
            [
                trial_name, trial_status, recruit_status, trial_code, description, apply_tip || '', entry_tip || '', confirm_tip || '', track_tip || '',
                exit_tip || '', group_info_template || '', promotion_url, start_date, end_date || null, group_config || null, trialId
            ]
        );
        res.json({ success: true });
    } catch (error) {
        console.error('更新试验失败:', error);
        res.json({ success: false, message: error.message });
    }
});

// 修改创建试验的路由
router.post('/admin/trials', trialAuth, async (req, res) => {
    try {
        const userId = req.session.totemUID;
        const { trial_name, description, start_date, end_date, trial_status, recruit_status, trial_code, group_config } = req.body;

        // 如果没有提供状态，默认为准备中(0)
        const trialStatus = trial_status || 0;

        const [result] = await rds.query(
            `INSERT INTO trials (trial_name, description, start_date, end_date, principal_id, status, recruit_status, trial_code, group_config)
             VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
            [trial_name, description, start_date, end_date, userId, trialStatus, recruit_status, trial_code, group_config]
        );

        res.json({ success: true });
    } catch (error) {
        console.error('创建试验失败:', error);
        res.json({
            success: false,
            message: error.message || '创建试验失败'
        });
    }
});

// 获取每个状态的受试者数量
const getGroupCounts = async (trialId) => {
    try {
        const [records] = await rds.query(
            'SELECT status, COUNT(*) as count FROM trial_subjects WHERE trial_id = ? GROUP BY status',
            [trialId]
        );
        // 状态：0未报名，1已报名，2已登记，3已入组，4已退组，9已完成，5取消报名（报名后退出）6取消入组
        const counts = { '0': 0, '1': 0, '2': 0, '3': 0, '4': 0, '5': 0, '6':0, '9': 0 };
        records.forEach(record => { counts[record.status] = record.count; });
        return counts;
    } catch (error) {
        console.error('获取分组计数失败:', error);
        return { '0': 0, '1': 0, '2': 0, '3': 0, '4': 0, '5': 0, '6':0, '9': 0 };
    }
};

// 受试者管理
router.get('/admin/trials/:trialId/subjects', trialAuth, async (req, res) => {
    const { trialId } = req.params;
    const userId = req.session.totemUID;

    // 获取当前用户名
    const [[user]] = await rds.query(
        'SELECT real_name FROM eb_user WHERE uid = ?',
        [userId]
    );

    const [subjects] = await rds.query(
        `SELECT s.*, s.user_id, u.real_name, u.phone,
                 DATE_FORMAT(s.created_at, '%Y-%m-%d') as created_date,
                 DATE_FORMAT(s.apply_time, '%Y-%m-%d') as apply_date,
                 DATE_FORMAT(s.entry_time, '%Y-%m-%d') as entry_date,
                 DATE_FORMAT(s.group_time, '%Y-%m-%d %H:%i:%s') as group_time,
                 CASE s.status
                     WHEN 0 THEN '未报名'
                     WHEN 1 THEN '已报名'
                     WHEN 2 THEN '已入组'
                     WHEN 3 THEN '已在组'
                     WHEN 4 THEN '已退组'
                     WHEN 5 THEN '取消报名'
                     WHEN 6 THEN '取消入组'
                     WHEN 9 THEN '已完成'
                 END as status_text,
                 CASE s.group_type
                     WHEN 1 THEN '试验组'
                     WHEN 2 THEN '对照组'
                     WHEN 9 THEN '观察员'
                     ELSE '未分组'
                 END as group_type_text
              FROM trial_subjects s
              LEFT JOIN eb_user u ON s.user_id = u.uid
              WHERE s.trial_id = ?
              ORDER BY s.group_type ASC`,
        [trialId]
    );

    const [[trial]] = await rds.query('SELECT * FROM trials WHERE id = ?', [trialId]);

    // 获取每个状态的受试者数量
    const groupCounts = await getGroupCounts(trialId);

    // 获取每个受试者的最新备注信息
    for (const subject of subjects) {
        const [profiles] = await rds.query(
            `SELECT p.*, u.real_name as operator_name, p.add_time
             FROM eb_user_profile p
             LEFT JOIN eb_user u ON p.aid = u.uid
             WHERE p.uid = ? AND p.type = ?
             ORDER BY p.add_time DESC
             LIMIT 1`,
            [subject.user_id, `trial_${subject.trial_id}_subject_${subject.id}_profile`]
        );

        if (profiles.length > 0) {
            const profile = profiles[0];
            try {
                const memo = JSON.parse(profile.memo || '{}');
                subject.latest_profile = {
                    content: data.content || '',
                    created_at: moment.unix(profile.add_time).format('YYYY-MM-DD HH:mm:ss'),
                    operator_name: `${profile.atype}#${profile.aid}`
                };
            } catch (e) {
                subject.latest_profile = null;
            }
        } else {
            subject.latest_profile = null;
        }
    }

    res.render('trial/admin/subjects', {
        trial,
        subjects,
        userName: user.real_name,
        groupCounts
    });
});

// 受试者详情
router.get( [ '/admin/trials/:trialId/subjects/:subjectId', '/subjects/:subjectId' ], trialAuth, async (req, res) => {

    try {
        const { subjectId } = req.params;

        // 获取受试者信息
        const [[subject]] = await rds.query(
            `SELECT s.*, u.real_name, u.phone,
                CASE s.status
                    WHEN 0 THEN '未报名' WHEN 1 THEN '已报名' WHEN 2 THEN '已入组'
                    WHEN 3 THEN '已在组' WHEN 4 THEN '已退组' WHEN 5 THEN '已完成'
                END as status_text,
                CASE s.group_type
                    WHEN 1 THEN '试验组' WHEN 2 THEN '对照组' WHEN 9 THEN '观察员'
                    ELSE '未分组'
                END as group_type_text
             FROM trial_subjects s LEFT JOIN eb_user u ON s.user_id = u.uid
             WHERE s.id = ?`,
            [subjectId]
        );

        if (!subject) {
            return res.status(404).render('warn', { title: '受试者不存在', message: '未找到受试者', description: '请检查受试者ID是否正确' });
        }
        const userId = req.session.totemUID; const role = req.session.trialROLE;
        if ( role != 'trial-admin' && userId != subject.user_id ) return res.json({ success: false, message: '权限不足！' });

        // 获取试验信息
        const trialId = subject.trial_id;
        const [[trial]] = await rds.query('SELECT * FROM trials WHERE id = ?', [trialId]);
        if (!trial) {
            return res.status(404).render('warn', {
                title: '试验不存在',
                message: '未找到试验',
                description: '请检查试验ID是否正确'
            });
        }

        // 解析组信息用于显示
        if (subject.group_type > 0 && trial.group_info_template) {
            let template = trial.group_info_template;
            template = template.replace(/\{\{groupNo\}\}/g, subject.group_no || '');
            template = template.replace(/\{\{groupType\}\}/g, subject.group_type_text);
            subject.group_info = template;
        }

        // 获取补给信息 - 从 supply_info 字段解析
        let supplyInfo = { supplies: [] };
        if (subject.supply_info) {
            try {
                const supplies = JSON.parse(subject.supply_info);
                if (supplies && Array.isArray(supplies) && supplies.length > 0) {
                    supplyInfo.supplies = supplies;
                }
            } catch (error) {
                console.error('解析补给信息失败:', error);
            }
        }

        // 获取最新的档案备注
        const [profiles] = await rds.query(
            `SELECT p.*, u.real_name as operator_name
             FROM eb_user_profile p
             LEFT JOIN eb_user u ON p.aid = u.uid
             WHERE p.uid = ? AND p.type = ?
             ORDER BY p.add_time DESC
             LIMIT 1`,
            [subject.user_id, `trial_${subject.trial_id}_subject_${subject.id}_profile`]
        );

        let latestProfile = null;
        if (profiles.length > 0) {
            const profile = profiles[0];
            try {
                const memo = JSON.parse(profile.memo || '{}');
                latestProfile = {
                    content: data.content || '',
                    created_at: moment.unix(profile.add_time).format('YYYY-MM-DD HH:mm:ss'),
                    operator_name: `${profile.atype}#${profile.aid}`
                };
            } catch (e) {
                latestProfile = null;
            }
        }

        const hbs = subject.id == 1 ? 'trial/admin/subject' : 'trial/admin/subject'; //using subject-test for verification
        res.render(hbs, { trial, subject, supplyInfo, latestProfile });

    } catch (error) {
        console.error('获取受试者详情失败:', error);
        res.status(500).render('warn', {
            title: '系统错误',
            message: '获取受试者详情失败',
            description: error.message
        });
    }
});

// 用户端路由
router.get('/my/trials', trialAuth, async (req, res) => {
    const userId = req.session.totemUID;

    try {
        const [trials] = await rds.query(
            `SELECT t.*, COALESCE(ts.status, -1) as userStatus, ts.created_at as join_time
             FROM trials t
             LEFT JOIN trial_subjects ts ON t.id = ts.trial_id AND ts.user_id = ?
             ORDER BY t.created_at DESC`,
            [userId]
        );

        res.render('trial/my/trials', { trials });
    } catch (error) {
        console.error('获取试验列表失败:', error);
        res.render('warn', {
            title: '临床研究支持',
            message: '获取试验列表失败',
            description: error.message,
            icon: 'weui-icon-warn weui-icon_msg'
        });
    }
});

// 添加状态检查中间件
async function checkTrialAccess(req, res, next) {
    const { trialCode } = req.params;
    const userId = req.session.totemUID;

    // 获取试验信息
    const [[trial]] = await rds.query(
        'SELECT * FROM trials WHERE trial_code = ?',
        [trialCode]
    );

    if (!trial) {
        return res.render('warn', {
            title: '临床研究支持',
            message: '试验不存在',
            description: '请检查试验代码',
            icon: 'weui-icon-warn weui-icon_msg'
        });
    }

    // 检查或创建受试者记录
    let [[subject]] = await rds.query(
        'SELECT * FROM trial_subjects WHERE trial_id = ? AND user_id = ?',
        [trial.id, userId]
    );

    if (!subject) {
        // 创建初始记录
        const [result] = await rds.query(
            `INSERT INTO trial_subjects
             (trial_id, user_id, subject_no, status)
             VALUES (?, ?, ?, 0)`,
            [trial.id, userId, `${trialCode}-${String(userId).padStart(6, '0')}`]
        );
        [[subject]] = await rds.query(
            'SELECT * FROM trial_subjects WHERE id = ?',
            [result.insertId]
        );
    }

    // 检查路由访问权限
    const path = req.path.split('/')[1]; // 获取主要路由名称
    const validRoutes = {
        'apply': [0],
        'entry': [1],
        'confirm': [2],
        'track': [3],
        'exit': [3],
        'finish': [3]
    };

    if (validRoutes[path] && !validRoutes[path].includes(subject.status)) {
        return res.redirect('/apps/trial/my/trials');
    }

    req.trial = trial;
    req.subject = subject;
    next();
}

// 修改现有路由，添加状态检查中间件
router.get('/apply/:trialCode', trialAuth, checkTrialAccess, async (req, res) => {
    const [[user]] = await rds.query(
        'SELECT real_name, phone FROM eb_user WHERE uid = ?',
        [req.session.totemUID]
    );
    res.render('trial/apply', { trial: req.trial, user });
});

// 处理报名提交
router.post('/apply/:trialCode', upload.none(), trialAuth, checkTrialAccess, async (req, res) => {
    try {
        const applyInfo = JSON.parse(req.body.applyInfo);

        // 更新报名信息和状态
        await rds.query(
            `UPDATE trial_subjects
             SET status = 1,
                 apply_info = ?,
                 apply_time = CURRENT_TIMESTAMP,
                 updated_at = CURRENT_TIMESTAMP
             WHERE id = ?`,
            [JSON.stringify(applyInfo), req.subject.id]
        );

        res.redirect('/apps/trial/my/trials');
    } catch (error) {
        console.error('报名失败:', error);
        res.render('warn', {
            title: '临床研究支持',
            message: '报名失败',
            description: error.message || '请稍后重试',
            icon: 'weui-icon-warn weui-icon_msg'
        });
    }
});

// 入组登记路由
router.get('/entry/:trialCode', trialAuth, checkTrialAccess, async (req, res) => {
    const [[user]] = await rds.query(
        'SELECT real_name, phone FROM eb_user WHERE uid = ?',
        [req.session.totemUID]
    );
    // 获取用户之前的申请信息
    const [[subject]] = await rds.query(
        `SELECT apply_info
        FROM trial_subjects
        WHERE trial_id = ? AND user_id = ? AND status = 1`,
        [req.trial.id, req.session.totemUID]
    );

    const { trialCode } = req.params;
    if(trialCode === 'CT-BCH-2501')
        res.redirect('/apps/space-journey/game');
    else
        res.render('trial/entry', { trial: req.trial, user, subject, applyInfo: subject.apply_info });
});

// 处理入组登记提交
router.post('/entry/:trialCode', upload.none(), trialAuth, checkTrialAccess, async (req, res) => {
    try {
        const entryInfo = JSON.parse(req.body.entryInfo);

        // 更新入组信息和状态
        await rds.query(
            `UPDATE trial_subjects
             SET status = 2,
                 entry_info = ?,
                 entry_time = CURRENT_TIMESTAMP,
                 updated_at = CURRENT_TIMESTAMP
             WHERE id = ?`,
            [JSON.stringify(entryInfo), req.subject.id]
        );

        res.redirect('/apps/trial/my/trials');
    } catch (error) {
        console.error('入组登记失败:', error);
        res.render('warn', {
            title: '临床研究支持',
            message: '入组登记失败',
            description: error.message || '请稍后重试',
            icon: 'weui-icon-warn weui-icon_msg'
        });
    }
});

// 等待分组路由
router.get('/confirm/:trialCode', trialAuth, checkTrialAccess, async (req, res) => {
    const { trialCode } = req.params;
    if(trialCode === 'CT-BCH-2501')
        res.redirect('/apps/space-journey/game');
    else
        res.render('trial/confirm', {
            trial: req.trial,
            subject: req.subject
        });
});

// 在组试验跟踪
router.get('/track/:trialCode', trialAuth, async (req, res) => {
    const { trialCode } = req.params;
    const userId = req.session.totemUID;
    // 获取试验信息
    const [[trial]] = await rds.query( 'SELECT * FROM trials WHERE trial_code = ?', [trialCode]);

    if (!trial) { throw new Error('试验不存在'); }
    // 获取受试者信息
    const [[subject]] = await rds.query(
        'SELECT * FROM trial_subjects WHERE trial_id = ? AND user_id = ?',
        [trial.id, userId]
    );
    if (!subject) { throw new Error('您不是该试验的受试者'); }
    // 直接跳转到参试日志列表页面
    res.redirect(`/apps/trial/diary/list/${trial.id}`);
});

// 修改批准入组API
router.post( [ '/admin/trials/subjects/:subjectId/approve' , '/subjects/:subjectId/approve' ] , trialAuth, async (req, res) => {
    try {
        const { subjectId } = req.params;
        const { group_type } = req.body;

        // 检查当前状态
        const [[subject]] = await rds.query( 'SELECT status FROM trial_subjects WHERE id = ?', [subjectId]);
        if (!subject || subject.status !== 2) return res.json({ success: false, message: '只能批准已登记的受试者入组' });


        // 更新为入组状态
        await rds.query(
            `UPDATE trial_subjects SET status = 3, group_type = ?, entry_time = CURRENT_TIMESTAMP, updated_at = CURRENT_TIMESTAMP WHERE id = ?`,
            [group_type, subjectId]
        );

        res.json({ success: true });
    } catch (error) {
        console.error('批准入组失败:', error);
        res.json({
            success: false,
            message: error.message || '批准入组失败'
        });
    }
});

// 获取受试者详情
router.get( [ '/admin/trials/subjects/:subjectId/info', '/subjects/:subjectId/info' ],  trialAuth, async (req, res) => {
    try {
        const { subjectId } = req.params;

        const [[subject]] = await rds.query(
            `SELECT s.*, u.nickname, u.phone FROM trial_subjects s LEFT JOIN eb_user u ON s.user_id = u.uid WHERE s.id = ?`, [subjectId]
        );

        if (!subject) return res.json({ success: false, message: '受试者不存在' });
        const userId = req.session.totemUID; const role = req.session.trialROLE;
        if ( role != 'trial-admin' && userId != subject.user_id ) return res.json({ success: false, message: '权限不足！' });

        res.json({ success: true, subject });
    } catch (error) {
        console.error('获取受试者详情失败:', error);
        res.json({
            success: false,
            message: error.message || '获取受试者详情失败'
        });
    }
});

// 添加关注试验的路由
router.post('/my/trials/:trialId/follow', trialAuth, async (req, res) => {
    try {
        const { trialId } = req.params;
        const userId = req.session.totemUID;

        // 检查用户是否已经关注该试验
        const [[existingSubject]] = await rds.query(
            'SELECT * FROM trial_subjects WHERE trial_id = ? AND user_id = ?',
            [trialId, userId]
        );

        if (existingSubject) {
            return res.json({ success: false, message: '您已关注该试验' });
        }

        // 生成一个新的subject_no
        const subjectNo = `${trialId}-${String(userId).padStart(6, '0')}`;

        // 创建新的trial_subjects记录
        await rds.query(
            `INSERT INTO trial_subjects (trial_id, user_id, subject_no, status)
             VALUES (?, ?, ?, 0)`,
            [trialId, userId, subjectNo]
        );

        res.json({ success: true });
    } catch (error) {
        console.error('关注试验失败:', error);
        res.json({ success: false, message: error.message || '关注试验失败' });
    }
});

// 获取试验详情
router.get('/admin/trials/:id', trialAuth, async (req, res) => {
    try {
        const [[trial]] = await rds.query(
            'SELECT id, trial_name, trial_code, description, entry_tip, confirm_tip, promotion_url, start_date, end_date, apply_tip, track_tip, exit_tip, group_info_template, group_config FROM trials WHERE id = ?',
            [req.params.id]
        );

        res.json({ trial });
    } catch (error) {
        console.error('获取试验详情失败:', error);
        res.status(500).json({ error: '获取试验详情失败' });
    }
});

// 设置分组
router.post('/subjects/:subjectId/group', trialAuth, async (req, res) => {
    try {
        const { subjectId } = req.params;
        const { groupType, groupNote, groupNo } = req.body;

        const [[subject]] = await rds.query(`select * from trial_subjects where id = ${subjectId}`);
        if (!subject) return res.json({ success: false, message: '受试者不存在' });

        const trialId = subject.trial_id;
        // 如果分配了非零的组别，更新状态为已在组
        const newStatus = groupType === '0' ? 2 : 3;

        // 获取试验的分组提示信息和分组配置
        const [[trial]] = await rds.query( 'SELECT group_info_template, group_config FROM trials WHERE id = ?', [trialId]);

        // 获取分组配置
        let groupConfigs = [];
        let followUpConfig = null;
        let groupTypeName = '';

        if (trial.group_config && groupType !== '0') {
            try {
                groupConfigs = JSON.parse(trial.group_config);
                followUpConfig = groupConfigs.find(config => config.group_type == groupType);

                if (followUpConfig) {
                    groupTypeName = followUpConfig.group_name;
                }
            } catch (e) {
                console.error('解析分组配置失败:', e);
            }
        }

        // 使用默认值作为后备选项
        if (!groupTypeName) {
            if (groupType === '1') groupTypeName = '试验组';
            else if (groupType === '2') groupTypeName = '对照组';
            else if (groupType === '9') groupTypeName = '观察组';
            else groupTypeName = `分组${groupType}`;
        }

        // 根据分组类型设置不同的提示信息
        let groupInfo = '';
        if (trial.group_info_template) {
            groupInfo = trial.group_info_template
                .replace(/\{\{groupNo\}\}/g, groupNo)
                .replace(/\{\{groupType\}\}/g, groupTypeName);
        }

        // 计算随访相关日期
        let followUpDays = 0;
        let followUpDates = [];
        let dailyDiary = false;

        if (followUpConfig) {
            followUpDays = followUpConfig.duration || 0;
            followUpDates = followUpConfig.follow_up_dates || [];
            dailyDiary = followUpConfig.daily_diary || false;
        }

        // 将分组配置保存到subject记录中
        const followUpInfo = JSON.stringify({
            duration: followUpDays,
            follow_up_dates: followUpDates,
            daily_diary: dailyDiary,
            group_name: groupTypeName
        });

        await rds.query(
            `UPDATE trial_subjects
             SET status = ?, group_type = ?, group_note = ?, group_no = ?, group_time = NOW(),
             group_info = ?, follow_up_info = ?  WHERE id = ? AND trial_id = ?`,
            [
                newStatus, groupType, groupNote, groupNo,
                groupInfo, followUpInfo, subjectId, trialId
            ]
        );

        res.json({ success: true });
    } catch (error) {
        console.error('设置分组失败:', error);
        res.json({ success: false, message: error.message });
    }
});

// 退出试验
router.post('/subjects/:subjectId/exit', trialAuth, async (req, res) => {
    try {
        const { subjectId } = req.params;
        const { reason, description } = req.body;

        const [[subject]] = await rds.query(`select * from trial_subjects where id = ${subjectId}`);
        if (!subject) return res.json({ success: false, message: '受试者不存在' });
        const userId = req.session.totemUID; const role = req.session.trialROLE;
        if ( role != 'trial-admin' && userId != subject.user_id ) return res.json({ success: false, message: '权限不足！' });

        // 更新受试者状态为已退组
        await rds.query(
            `UPDATE trial_subjects SET status = 4, exit_reason = ?, exit_info = ?, exit_time = NOW() WHERE id = ?`,
            [ reason, description, subjectId ]
        );

        res.json({ success: true });
    } catch (error) {
        console.error('退出试验失败:', error);
        res.json({ success: false, message: error.message });
    }
});

// 完成试验
router.post('/subjects/:subjectId/finish', trialAuth, async (req, res) => {
    try {
        const { subjectId } = req.params;
        const { summary, effectiveness } = req.body;
        const finish_info = JSON.stringify( {summary, effectiveness} )

        const [[subject]] = await rds.query(`select * from trial_subjects where id = ${subjectId}`);
        if (!subject) return res.json({ success: false, message: '受试者不存在' });
        const userId = req.session.totemUID; const role = req.session.trialROLE;
        if ( role != 'trial-admin' && userId != subject.user_id ) return res.json({ success: false, message: '权限不足！' });

        // 更新受试者状态为已完成
        await rds.query(
            `UPDATE trial_subjects SET status = 9, finish_info = ?, finish_time = NOW() WHERE id = ?`,
            [ finish_info, subjectId ]
        );

        res.json({ success: true });
    } catch (error) {
        console.error('完成试验失败:', error);
        res.json({ success: false, message: error.message });
    }
});

// 参试日志列表
router.get('/diary/list/:trialId', trialAuth, async (req, res) => {
    try {
        const { trialId } = req.params;
        const { subject_id } = req.query;
        const userId = req.session.totemUID;
        const role = req.session.trialROLE;

        // 获取受试者信息
        let subjectId;
        if (role === 'trial-admin' && subject_id) {
            // 管理员查看指定受试者的日记
            const [[subject]] = await rds.query(
                'SELECT id FROM trial_subjects WHERE id = ? AND trial_id = ?',
                [subject_id, trialId]
            );
            if (!subject) {
                throw new Error('受试者不存在');
            }
            subjectId = subject.id;
        } else {
            // 受试者查看自己的日记
            const [[subject]] = await rds.query(
                'SELECT id FROM trial_subjects WHERE trial_id = ? AND user_id = ?',
                [trialId, userId]
            );
            if (!subject) {
                throw new Error('您不是该试验的受试者');
            }
            subjectId = subject.id;
        }

        // 获取日记列表
        const [diaries] = await rds.query(
            `SELECT * FROM trial_diaries
             WHERE subject_id = ?
             ORDER BY diary_date DESC`,
            [subjectId]
        );

        // 解析每条日记的content字段
        diaries.forEach(diary => {
            if (diary.content) {
                const content = JSON.parse(diary.content);
                diary.content = content;
            }
        });

        // 获取试验信息
        const [[trial]] = await rds.query(
            'SELECT * FROM trials WHERE id = ?',
            [trialId]
        );

        res.render('trial/diary/list', {
            trial,
            diaries,
            isAdmin: role === 'trial-admin',
        });
    } catch (error) {
        console.error('获取日记列表失败:', error);
        res.render('warn', {
            title: '临床研究支持',
            message: '获取日记列表失败',
            description: error.message,
            icon: 'weui-icon-warn weui-icon_msg'
        });
    }
});

// 创建日记页面
router.get('/diary/create/:trialId', trialAuth, async (req, res) => {
    try {
        const { trialId } = req.params;
        const userId = req.session.totemUID;

        // 获取试验信息
        const [[trial]] = await rds.query(
            'SELECT * FROM trials WHERE id = ?',
            [trialId]
        );

        if (!trial) {
            throw new Error('试验不存在');
        }

        // 获取受试者信息
        const [[subject]] = await rds.query(
            'SELECT id FROM trial_subjects WHERE trial_id = ? AND user_id = ?',
            [trialId, userId]
        );

        if (!subject) {
            throw new Error('您不是该试验的受试者');
        }

        res.render('trial/diary/edit', {
            trial,
            diary: null,  // 创建时没有日记数据
            today: moment().format('YYYY-MM-DD'),
        });
    } catch (error) {
        console.error('获取创建日记页面失败:', error);
        res.render('warn', {
            title: '临床研究支持',
            message: '获取创建日记页面失败',
            description: error.message,
            icon: 'weui-icon-warn weui-icon_msg'
        });
    }
});

// 处理创建日记的表单提交
router.post('/diary/create/:trialId', trialAuth, async (req, res) => {
    try {
        const { trialId } = req.params;
        const userId = req.session.totemUID;

        // 获取受试者信息
        const [[subject]] = await rds.query(
            'SELECT id FROM trial_subjects WHERE trial_id = ? AND user_id = ?',
            [trialId, userId]
        );

        if (!subject) {
            throw new Error('您不是该试验的受试者');
        }

        const { diary_date, ...content } = req.body;

        // 确保 rehabilitation_types 和 rehabilitation_channels 总是数组
        content.rehabilitation_types = Array.isArray(content.rehabilitation_types)
            ? content.rehabilitation_types
            : content.rehabilitation_types ? [content.rehabilitation_types] : [];

        content.rehabilitation_channels = Array.isArray(content.rehabilitation_channels)
            ? content.rehabilitation_channels
            : content.rehabilitation_channels ? [content.rehabilitation_channels] : [];

        // 创建日记
        await rds.query(
            `INSERT INTO trial_diaries (
                subject_id, trial_id, diary_date, content
            ) VALUES (?, ?, ?, ?)`,
            [
                subject.id,
                trialId,
                diary_date,
                JSON.stringify(content)
            ]
        );

        res.redirect(`/apps/trial/diary/list/${trialId}`);
    } catch (error) {
        console.error('创建日记失败:', error);
        res.render('warn', {
            title: '临床研究支持',
            message: '创建日记失败',
            description: error.message,
            icon: 'weui-icon-warn weui-icon_msg'
        });
    }
});

// 获取日记详情
router.get('/diary/:diaryId', trialAuth, async (req, res) => {
    try {
        const { diaryId } = req.params;
        const userId = req.session.totemUID;

        // 获取日记详情
        const [[diary]] = await rds.query(
            `SELECT d.*, s.user_id, t.trial_name, t.trial_code, t.id as trial_id
             FROM trial_diaries d
             JOIN trial_subjects s ON d.subject_id = s.id
             JOIN trials t ON d.trial_id = t.id
             WHERE d.id = ?`,
            [diaryId]
        );

        if (!diary) {
            throw new Error('日记不存在');
        }

        // 检查权限（允许管理员和本人查看）
        const role = req.session.trialROLE;
        if (role !== 'trial-admin' && diary.user_id !== userId) {
            throw new Error('您没有权限查看此日记');
        }

        // 解析content字段中的JSON数据到diary对象中
        if (diary.content) {
            const content = JSON.parse(diary.content);
            Object.assign(diary, content);
        }

        res.render('trial/diary/view', {
            diary,
            trial: {
                id: diary.trial_id,
                trial_name: diary.trial_name,
                trial_code: diary.trial_code
            },
            isAdmin: role === 'trial-admin',
            userId: userId
        });
    } catch (error) {
        console.error('获取日记详情失败:', error);
        res.render('warn', {
            title: '临床研究支持',
            message: '获取日记详情失败',
            description: error.message,
            icon: 'weui-icon-warn weui-icon_msg'
        });
    }
});

// 获取日记编辑页面
router.get('/diary/:diaryId/edit', trialAuth, async (req, res) => {
    try {
        const { diaryId } = req.params;
        const userId = req.session.totemUID;

        // 获取日记详情
        const [[diary]] = await rds.query(
            `SELECT d.*, s.user_id, t.trial_name, t.trial_code, t.id as trial_id
             FROM trial_diaries d
             JOIN trial_subjects s ON d.subject_id = s.id
             JOIN trials t ON d.trial_id = t.id
             WHERE d.id = ?`,
            [diaryId]
        );

        if (!diary || diary.user_id !== userId) {
            throw new Error(`您[${userId}]没有权限编辑此日记[${diaryId}]`);
        }

        // 解析content字段
        if (diary.content) {
            const content = JSON.parse(diary.content);
            // 将content中的字段展开到diary对象中，以便在编辑表单中显示
            Object.assign(diary, content);

            // 确保 media_files 是正确的格式
            if (content.media_files) {
                diary.media_files = typeof content.media_files === 'string'
                    ? content.media_files
                    : JSON.stringify(content.media_files);
            }
        }

        res.render('trial/diary/edit', {
            diary,
            trial: {
                id: diary.trial_id,
                trial_name: diary.trial_name,
                trial_code: diary.trial_code
            },
            today: moment().format('YYYY-MM-DD'),
        });
    } catch (error) {
        console.error('获取日记编辑页面失败:', error);
        res.render('warn', {
            title: '临床研究支持',
            message: '获取日记编辑页面失败',
            description: error.message,
            icon: 'weui-icon-warn weui-icon_msg'
        });
    }
});

// 编辑日记
router.post('/diary/:diaryId/edit', trialAuth, async (req, res) => {
    try {
        const { diaryId } = req.params;
        const userId = req.session.totemUID;

        // 检查权限
        const [[diary]] = await rds.query(
            `SELECT d.*, s.user_id, t.id as trial_id
             FROM trial_diaries d
             JOIN trial_subjects s ON d.subject_id = s.id
             JOIN trials t ON d.trial_id = t.id
             WHERE d.id = ?`,
            [diaryId]
        );

        if (!diary || diary.user_id !== userId) {
            return res.status(403).json({
                success: false,
                message: '您没有权限编辑此日记'
            });
        }

        const { diary_date, ...content } = req.body;

        // 确保 rehabilitation_types 和 rehabilitation_channels 总是数组
        content.rehabilitation_types = Array.isArray(content.rehabilitation_types)
            ? content.rehabilitation_types
            : content.rehabilitation_types ? [content.rehabilitation_types] : [];

        content.rehabilitation_channels = Array.isArray(content.rehabilitation_channels)
            ? content.rehabilitation_channels
            : content.rehabilitation_channels ? [content.rehabilitation_channels] : [];

        // 更新日记
        await rds.query(
            `UPDATE trial_diaries SET
                diary_date = ?,
                content = ?,
                updated_at = CURRENT_TIMESTAMP
             WHERE id = ?`,
            [
                diary_date,
                JSON.stringify(content),
                diaryId
            ]
        );

        // 成功后重定向到日记列表页面
        res.redirect(`/apps/trial/diary/list/${diary.trial_id}`);
    } catch (error) {
        console.error('更新日记失败:', error);
        res.render('warn', {
            title: '临床研究支持',
            message: '更新日记失败',
            description: error.message,
            icon: 'weui-icon-warn weui-icon_msg'
        });
    }
});

router.get('/hello', async (req,res) => {
    res.render('hello');
});

router.get('/hello2', async (req,res) => {
    res.render('trial/hello2');
});

// 授权码路由
router.get('/grant/:trialId', async (req, res) => {
    res.render('trial/grant', {
        trialId: req.params.trialId
    });
});

// 处理授权
router.post('/grant/:trialId', upload.none(), async (req, res) => {
    try {
        const { trialId } = req.params;
        const { code } = req.body;
        const userId = req.session.totemUID;

        // 验证授权码格式
        const grantCode = `GRANT-T${trialId}-ADMIN`;
        if (code !== grantCode) {
            return res.redirect('/apps/trial');
        }

        // 获取用户当前角色
        const [[user]] = await rds.query(
            'SELECT roles FROM eb_user WHERE uid = ?',
            [userId]
        );

        if (!user) {
            return res.redirect('/apps/trial');
        }

        // 解析现有角色
        const roles = user.roles ? user.roles.split(' ') : [];

        // 添加新角色（如果不存在）
        if (!roles.includes('trial-admin')) {
            roles.push('trial-admin');

            // 更新用户角色
            await rds.query(
                'UPDATE eb_user SET roles = ? WHERE uid = ?',
                [roles.join(' '), userId]
            );
        }

        // 显示成功提示并重定向
        res.render('trial/grant-success', {
            message: '授权成功',
            redirectUrl: '/apps/clear'
        });
    } catch (error) {
        console.error('授权失败:', error);
        res.redirect('/apps/trial');
    }
});

// 更新补给信息
router.post('/subjects/:subjectId/update-supply', trialAuth, async (req, res) => {
    try {
        const { subjectId } = req.params;
        const { index, supply } = req.body;

        // 获取受试者信息
        const [[subject]] = await rds.query('SELECT * FROM trial_subjects WHERE id = ?', [subjectId]);
        if (!subject) return res.json({ success: false, message: '受试者不存在' });

        // 获取现有的补给记录
        let supplies = [];
        if (subject.supply_info) {
            try {
                supplies = JSON.parse(subject.supply_info);
                if (!Array.isArray(supplies)) {
                    supplies = [];
                }
            } catch (error) {
                console.error('解析现有补给信息失败:', error);
                supplies = [];
            }
        }

        // 判断是新增还是编辑
        if (index >= 0 && index < supplies.length) {
            // 编辑现有记录
            supplies[index] = supply;
        } else {
            // 添加新记录
            // 确保 status 中有 timestamp
            if (!supply.status.timestamp) {
                supply.status.timestamp = new Date().toISOString().slice(0, 19).replace('T', ' ');
            }
            supplies.push(supply);
        }

        // 更新补给信息
        await rds.query(
            'UPDATE trial_subjects SET supply_info = ? WHERE id = ?',
            [JSON.stringify(supplies), subjectId]
        );

        // 如果状态变为已送达，创建任务提醒用户 (保留原有逻辑)
        if (supply.status.code === 'delivered') {
            try {
                // 向用户发送提示任务
                if (typeof task !== 'undefined') { // 检查 task 模块是否存在
                    await task.assignTask(
                        "uid", // 任务发放对象的识别形式，固定值
                        subject.user_id, // 通知发放对象用户号
                        "trial_supply_delivered", // 固定值
                        `您的试验用品已送达，请确认收货`, // 任务标题
                        "Wework", // 固定值
                        `https://totemlife.cn/apps/space-journey/game`, // 任务链接
                        `您的试验用品已送达，请进入能源补给舱确认收货，然后开始您的星际旅程`, // 任务描述
                        "pending" // 任务状态
                    );
                }
            } catch (error) {
                console.error('创建提示任务失败:', error);
            }
        }

        res.json({ success: true });
    } catch (error) {
        console.error('更新补给信息失败:', error);
        res.json({ success: false, message: error.message });
    }
});

// 取消报名、取消入组路由
router.post('/subjects/:subjectId/cancel', trialAuth, async (req, res) => {
    try {
        const { subjectId } = req.params;
        const { reason, description } = req.body;

        if (!reason || !description) {
            return res.json({ success: false, message: '请提供取消原因和详细说明' });
        }

        // 获取受试者信息
        const [[subject]] = await rds.query( 'SELECT id, user_id, trial_id, status FROM trial_subjects WHERE id = ?', [subjectId]);
        if (!subject) return res.json({ success: false, message: '受试者不存在' });
        const userId = req.session.totemUID; const role = req.session.trialROLE;
        if ( role != 'trial-admin' && userId != subject.user_id ) return res.json({ success: false, message: '权限不足！' });

        if (subject.status !== 1 && subject.status !== 2 ) {
            return res.json({ success: false, message: '只能取消已报名状态或已入组状态的受试者' });
        }

        const exitInfo = JSON.stringify({
            reason, description, operator: `U#${userId}`, moment: moment().format('YYYY-MM-DD HH:mm:ss')
        });

        // 更新受试者状态为5（取消报名）或者6（取消入组）
        await rds.query(
            `UPDATE trial_subjects SET status = ${subject.status + 4}, exit_reason = ?, exit_info = ?, exit_time = NOW() WHERE id = ?`,
            [reason, exitInfo, subjectId]
        );

        res.json({ success: true, message: '取消报名或取消入组成功' });
    } catch (error) {
        console.error('取消报名或取消入组出错:', error);
        res.json({ success: false, message: '操作失败，请重试' });
    }
});

// 获取档案备注
router.get('/subjects/:subjectId/profiles', trialAuth, async (req, res) => {
    try {
        const { subjectId } = req.params;

        // 获取受试者信息
        const [[subject]] = await rds.query( 'SELECT id, user_id, trial_id FROM trial_subjects WHERE id = ?', [subjectId]);
        if (!subject) return res.json({ success: false, message: '受试者不存在' });
        const userId = req.session.totemUID; const role = req.session.trialROLE;
        if ( role != 'trial-admin' && userId != subject.user_id ) return res.json({ success: false, message: '权限不足！' });

        const trial_id = subject.trial_id;
        // 获取备注档案 - 修复档案类型
        const [profiles] = await rds.query(
            `SELECT p.*, u.real_name as operator_name
             FROM eb_user_profile p
             LEFT JOIN eb_user u ON p.aid = u.uid
             WHERE p.uid = ? AND p.type = ?
             ORDER BY p.add_time DESC`,
            [subject.user_id, `trial_${subject.trial_id}_subject_${subject.id}_profile`]
        );

        // 处理附件路径
        profiles.forEach(profile => {
            try {
                const data = JSON.parse(profile.memo || '{}');
                profile.content = data.content || '';
                profile.secret_level = data.secret_level || 0;
                profile.created_at = moment.unix(profile.add_time).format('YYYY-MM-DD HH:mm:ss');
            } catch (e) {
                profile.content = '';
                profile.secret_level = 0;
            }
        });

        res.json({ success: true, profiles });
    } catch (error) {
        console.error('获取备注档案失败:', error);
        res.json({ success: false, message: error.message });
    }
});

// 添加档案备注 - 只有管理员可以使用
router.post( [ '/subjects/:subjectId/profile', '/subjects/:subjectId/update-status'], trialAuth, fileUpload.single('attachment'), async (req, res) => {
    try {
        const { subjectId } = req.params;
        const { content, secretLevel, trialId, confidentiality, attachmentUrls } = req.body;

        if (!content) {
            return res.json({ success: false, message: '备注内容不能为空' });
        }

        // 获取受试者信息
        const [[subject]] = await rds.query( 'SELECT id, user_id, trial_id FROM trial_subjects WHERE id = ?', [subjectId]);
        if (!subject) return res.json({ success: false, message: '受试者不存在' });

        // 构建备注数据
        const profileData = { content };

        // 插入备注档案
        await rds.query(
            `INSERT INTO eb_user_profile
             (uid, atype, aid, type, title, memo, attachment_urls, confidentiality, add_time)
             VALUES (?, ?, ?, ?, ?, ?, ?, ?,  UNIX_TIMESTAMP())`,
            [
                subject.user_id, 'user', req.session.totemUID,
                `trial_${subject.trial_id}_subject_${subject.id}_profile`, `试验#${subject.trial_id}受试者#${subject.id}的档案备注`,
                JSON.stringify(profileData), JSON.stringify(attachmentUrls), confidentiality
            ]
        );

        res.json({ success: true });
    } catch (error) {
        console.error('添加备注档案失败:', error);
        res.json({ success: false, message: error.message });
    }
});

// 获取受试者收件人信息
router.get('/subjects/:subjectId/receiver-info', trialAuth, async (req, res) => {
    try {
        const subjectId = req.params.subjectId;
        const [[subject]] = await rds.query('SELECT * FROM trial_subjects WHERE id = ?', [subjectId]);

        if (!subject) {
            return res.status(404).json({
                success: false,
                message: '未找到受试者'
            });
        }

        let receiver = {
            name: '',
            phone: '',
            address: ''
        };

        // 首先尝试从 supply_info 获取最近的收件人信息
        if (subject.supply_info) {
            try {
                const supplies = JSON.parse(subject.supply_info);
                if (supplies && Array.isArray(supplies) && supplies.length > 0) {
                    // 获取最新的一条记录
                    const latestSupply = supplies[supplies.length - 1];
                    if (latestSupply && latestSupply.receiver) {
                        receiver = {
                            name: latestSupply.receiver.name || '',
                            phone: latestSupply.receiver.phone || '',
                            address: latestSupply.receiver.address || ''
                        };
                    }
                }
            } catch (error) {
                console.error('解析补给信息失败:', error);
            }
        }

        // 如果没有找到收件人信息，则尝试从 entry_info 获取
        if (!receiver.name && subject.entry_info) {
            try {
                const entryInfo = JSON.parse(subject.entry_info || '{}');
                const applyInfo = JSON.parse(subject.apply_info || '{}');
                // 整合收件人信息
                let name = entryInfo.recipient_name || entryInfo.guardian_name || applyInfo.contact_name || '';
                let phone = entryInfo.recipient_phone || entryInfo.guardian_phone || applyInfo.contact_phone || '';
                const entry_address = entryInfo.shipping_address ? entryInfo.shipping_address.province || '' + entryInfo.shipping_address.detail || '' : null;
                let address = entryInfo.recipient_address || entry_address || applyInfo.contact_address || '';

                if (name || phone || address) {
                    receiver = {
                        name,
                        phone,
                        address
                    };
                }
            } catch (error) {
                console.error('解析入组信息失败:', error);
            }
        }

        return res.json({
            success: true,
            receiver
        });
    } catch (error) {
        console.error('获取收件人信息失败:', error);
        return res.status(500).json({
            success: false,
            message: '服务器错误'
        });
    }
});

// 获取补给信息
router.get('/subjects/:subjectId/supply-info', trialAuth, async (req, res) => {
    try {
        const subjectId = req.params.subjectId;
        const [[subject]] = await rds.query('SELECT supply_info FROM trial_subjects WHERE id = ?', [subjectId]);

        if (!subject) {
            return res.status(404).json({
                success: false,
                message: '未找到受试者'
            });
        }

        let supplies = [];
        if (subject.supply_info) {
            try {
                supplies = JSON.parse(subject.supply_info);
                if (!Array.isArray(supplies)) {
                    supplies = [];
                }
            } catch (error) {
                console.error('解析补给信息失败:', error);
                supplies = [];
            }
        }

        return res.json({
            success: true,
            supplies
        });
    } catch (error) {
        console.error('获取补给信息失败:', error);
        return res.status(500).json({
            success: false,
            message: '服务器错误'
        });
    }
});

function getSubjectDayStats(subject, trial) {

    const dayStats = {}
    // 设置日期相关字段
    dayStats.current_date = moment().format('YYYY-MM-DD');
    dayStats.created_date = subject.created_at ? moment(subject.created_at).local().format('YYYY-MM-DD') : '';
    dayStats.updated_date = subject.updated_at ? moment(subject.updated_at).local().format('YYYY-MM-DD') : '';
    dayStats.apply_date = subject.apply_time ? moment(subject.apply_time).local().format('YYYY-MM-DD') : '';
    dayStats.entry_date = subject.entry_time ? moment(subject.entry_time).local().format('YYYY-MM-DD') : '';
    dayStats.group_date = subject.group_time ? moment(subject.group_time).local().format('YYYY-MM-DD') : '';
    dayStats.start_date = subject.start_date ? moment(subject.start_date).local().format('YYYY-MM-DD') : '';
    dayStats.exit_date = subject.exit_time ? moment(subject.exit_time).local().format('YYYY-MM-DD') : '';
    dayStats.finish_date = subject.finish_time ? moment(subject.finish_time).local().format('YYYY-MM-DD') : '';

    dayStats.current_time = moment().format('YYYY-MM-DD HH:mm:ss');
    dayStats.created_time = subject.created_at ? moment(subject.created_at).local().format('YYYY-MM-DD HH:mm:ss') : '';
    dayStats.updated_time = subject.updated_at ? moment(subject.updated_at).local().format('YYYY-MM-DD HH:mm:ss') : '';
    dayStats.apply_time = subject.apply_time ? moment(subject.apply_time).local().format('YYYY-MM-DD HH:mm:ss') : '';
    dayStats.entry_time = subject.entry_time ? moment(subject.entry_time).local().format('YYYY-MM-DD HH:mm:ss') : '';
    dayStats.group_time = subject.group_time ? moment(subject.group_time).local().format('YYYY-MM-DD HH:mm:ss') : '';
    dayStats.start_time = subject.start_date ? moment(subject.start_date).local().format('YYYY-MM-DD HH:mm:ss') : '';
    dayStats.exit_time = subject.exit_time ? moment(subject.exit_time).local().format('YYYY-MM-DD HH:mm:ss') : '';
    dayStats.finish_time = subject.finish_time ? moment(subject.finish_time).local().format('YYYY-MM-DD HH:mm:ss') : '';

    dayStats.days_since_created = ((m) => m.isValid() ? moment().diff(m, 'days') : 0)(moment(dayStats.created_time));
    dayStats.days_since_updated = ((m) => m.isValid() ? moment().diff(m, 'days') : 0)(moment(dayStats.updated_time));
    dayStats.days_since_apply = ((m) => m.isValid() ? moment().diff(m, 'days') : 0)(moment(dayStats.anpply_time));
    dayStats.days_since_entry = ((m) => m.isValid() ? moment().diff(m, 'days') : 0)(moment(dayStats.entry_time));
    dayStats.days_since_group = ((m) => m.isValid() ? moment().diff(m, 'days') : 0)(moment(dayStats.group_time));
    dayStats.days_since_start = ((m) => m.isValid() ? moment().diff(m, 'days') : 0)(moment(dayStats.start_time));
    dayStats.days_since_exit = ((m) => m.isValid() ? moment().diff(m, 'days') : 0)(moment(dayStats.exit_time));
    dayStats.days_since_finish = ((m) => m.isValid() ? moment().diff(m, 'days') : 0)(moment(dayStats.finish_time));

    dayStats.progress = 0;
    dayStats.day_remaining = 0;
    const groupConf = getSubjectGroupConf(subject, trial);
    if (dayStats.start_time && groupConf.duration) {
        dayStats.day_remaining = Math.max(0, groupConf.duration - dayStats.days_since_start);
        dayStats.progress = Math.min(100, Math.max(0, Math.floor((dayStats.days_since_start / groupConf.duration) * 100)));
    }

    dayStats.alerts=[];
    dayStats.warnings=[];
    dayStats.tips=[];

    if (subject.status === 1) {
        if (dayStats.days_since_apply >= 30) {
            dayStats.alerts.push(`等待面诊入组超过30天`);
        } else if (dayStats.days_since_entry >= 10) {
            dayStats.warnings.push(`等待面诊入组超过10天`);
        } else if (dayStats.days_since_entry >= 5) {
            dayStats.tips.push(`等待面诊入组超过5天`);
        }
    }
    if (subject.status === 2) {
        // 待分组状态
        if (dayStats.days_since_entry >= 5) {
            dayStats.alerts.push(`等待分配编组超过5天`);
        } else if (dayStats.days_since_entry >= 3) {
            dayStats.warnings.push(`等待分配编组超过3天`);
        } else if (dayStats.days_since_entry >= 1) {
            dayStats.tips.push(`等待分配编组超过1天`);
        }
    }
    if (subject.status === 3) {
        // 已分组状态
        if (!dayStats.start_time) {
            if (dayStats.days_since_group >= 5) {
                dayStats.alerts.push(`分组后未开始试验超过5天`);
            } else if (dayStats.days_since_group >= 3) {
                dayStats.warnings.push(`分组后未开始试验超过3天`);
            } else if (dayStats.days_since_group >= 1) {
                dayStats.tips.push(`分组后未开始试验超过1天`);
            }
        }else{
            if ( (dayStats.days_since_start -  groupConf.duration) >= 5){
                dayStats.alerts.push(`结束日期超过5天`);
            }else if ( (dayStats.days_since_start -  groupConf.duration) >= 1){
                dayStats.warnings.push('结束日期超过1天');
            }else if ( (dayStats.days_since_start -  groupConf.duration) >= -1){
                dayStats.tips.push('离预计结束日期还有1天');
            }
        }
    }

    return dayStats;
}

function getTrialGroupConfigs(trial) {
    // 获取试验的分组配置
    let groupConfigs = {};
    try {
        const groupConfig = JSON.parse(trial.group_config || '[]');
        if (Array.isArray(groupConfig)) {
            groupConfig.forEach(group => {
                groupConfigs[group.group_type] = {
                    type: group.group_type,
                    name: group.group_name,
                    daily_diary: group.daily_diary,
                    followup_days: group.follow_up_dates || [],
                    duration: group.duration || 30
                };
            });
        }
    } catch (error) {
        console.error('解析分组配置失败:', error);
    }
    return groupConfigs;
}

function getSubjectGroupConf(subject, trial) {
    const groupConfigs = getTrialGroupConfigs(trial);
    const groupConf = groupConfigs[subject.group_type] || {
        type: 0,
        name: '未分组',
        daily_diary: false,
        followup_days: [],
        duration: 30
    };
    return groupConf;
}

// 试验看板页面
router.get('/admin/trials/:trialId/dashboard', trialAuth, async (req, res) => {
    const now = new Date();
    try {
        const trialId = req.params.trialId;

        // 获取试验信息
        const [[trial]] = await rds.query(`SELECT * FROM trials WHERE id = ?`, [trialId]);
        if (!trial) {
            return res.status(404).send('试验不存在');
        }

        // 获取所有受试者
        const [subjects] = await rds.query(
            `SELECT s.*, e.uid, e.real_name FROM trial_subjects s LEFT JOIN eb_user e ON s.user_id = e.uid WHERE s.trial_id = ?  ORDER BY s.id DESC`,
            [trialId]
        );

        // 获取每个受试者的随访任务统计
        const subjectsWithStats = await Promise.all(subjects.map(async (subject) => {
            // 预设值
            subject.alerts = [];
            subject.warnings = [];
            subject.tips = [];

            // 解析入组信息
            try {
                subject.entry_info = JSON.parse(subject.entry_info || '{}');
            } catch (e) {
                subject.entry_info = {};
            }

            // 获取受试者的分组配置
            const groupConf = getSubjectGroupConf(subject, trial);
            subject.groupConfig = groupConf;

            const dayStats = getSubjectDayStats(subject, trial);
            subject.alerts = subject.alerts.concat(dayStats.alerts);
            subject.warnings = subject.warnings.concat(dayStats.warnings);
            subject.tips = subject.tips.concat(dayStats.tips);
            Object.assign(subject, dayStats);
            subject.dayStats = dayStats;

            // 获取随访任务完成情况
            let taskStats = {
                total: groupConf.followup_days.length,
                completed: 0,
                pending: 0,
                overdue: 0,
                progress: 0,
                alerts: [],
                warnings: [],
                tips: [],
            };

            if (subject.start_time && groupConf.followup_days && groupConf.followup_days.length > 0) {
                const startDate = new Date(subject.start_time);
                const currentDay = Math.ceil((now - startDate) / (1000 * 60 * 60 * 24));

                // 获取已完成的随访记录
                const [followups] = await rds.query(
                    `SELECT * FROM trial_follow_up WHERE subject_id = ?`,
                    [subject.id]
                );

                // 提取已完成的随访点
                const completedDays = new Set();
                followups.forEach(followup => {
                    try {
                        const content = JSON.parse(followup.content || '{}');
                        if (content.targetDay) {
                            completedDays.add(parseInt(content.targetDay));
                        }
                    } catch (e) {
                        // 忽略解析错误
                    }
                });

                taskStats.completed = completedDays.size;
                taskStats.progress = Math.min(100, Math.max(0, Math.floor((taskStats.completed / taskStats.total) * 100)));

                // 找出待完成的随访点
                const pendingFollowups = groupConf.followup_days
                    .filter(day => currentDay >= day && !completedDays.has(day))
                    .map(day => ({
                        day,
                        date: new Date(startDate.getTime() + (day - 1) * 24 * 60 * 60 * 1000),
                        daysOverdue: currentDay - day
                    }));

                taskStats.pending = pendingFollowups.length;
                taskStats.overdue = pendingFollowups.filter(f => f.daysOverdue > 0).length;

                // 随访任务未完成情况
                if (taskStats.overdue > 2) {
                    taskStats.alerts.push(`超过2个随访任务逾期`);
                } else if (taskStats.overdue > 1) {
                    taskStats.warnings.push('超过1个随访任务逾期');
                } else if (taskStats.overdue == 1) {
                    taskStats.tips.push('1个随访任务待完成');
                }
            }

            subject.taskStats = taskStats;
            subject.alerts = subject.alerts.concat(taskStats.alerts);
            subject.warnings = subject.warnings.concat(taskStats.warnings);
            subject.tips = subject.tips.concat(taskStats.tips);

            // 获取打卡情况
            let diaryStats = {
                total: 0,
                completed: 0,
                progress: 0,
                overdue: 0,
                days_since_last_diary: 0,
                alerts: [],
                warnings: [],
                tips: []
            };

            if (subject.start_time ) {
                // 获取总打卡次数
                diaryStats.total = groupConf.duration;
                const [[record]] = await rds.query(
                    `SELECT COUNT(*) AS diary_count FROM trial_diaries WHERE diary_date
                    BETWEEN '${dayStats.start_date}' AND '${dayStats.current_date}' AND subject_id = ${subject.id};`
                );
                diaryStats.completed = record.diary_count;
                diaryStats.overdue = dayStats.days_since_start - record.diary_count;

                // 获取最后一次打卡日期
                const [[last_diary]] = await rds.query( `SELECT diary_date FROM trial_diaries WHERE subject_id = ?  ORDER BY diary_date DESC LIMIT 1`, [subject.id]);

                if (last_diary) {
                    const lastDiaryDate = new Date(last_diary.diary_date);
                    diaryStats.days_since_last_diary = Math.floor((now - lastDiaryDate) / (1000 * 60 * 60 * 24));
                } else {
                    diaryStats.days_since_last_diary = subject.days_since_start;
                }

                diaryStats.progress = Math.min(100, Math.max(0, Math.floor((diaryStats.completed / diaryStats.total) * 100)));

                if (groupConf.daily_diary) {
                    // 检查连续未打卡打卡天数
                    if (diaryStats.days_since_last_diary >= 3) {
                        diaryStats.alerts.push(`连续3天未打卡`);
                    } else if (diaryStats.days_since_last_diary >= 2) {
                        diaryStats.warnings.push('连续2天未打卡');
                    } else if (diaryStats.days_since_last_diary >= 1) {
                        diaryStats.tips.push('今天还没打卡');
                    }
                    // 简化处理累计未打卡天数
                    const missedDays = Math.min(30, subject.days_since_start) - diaryStats.completed;
                    if (missedDays >= 5) {
                        diaryStats.alerts.push(`30日内累计达5天未打卡`);
                    } else if (missedDays >= 3) {
                        diaryStats.warnings.push(`30日内累计达3天未打卡`);
                    } else if (missedDays >= 1) {
                        diaryStats.tips.push(`30日内累计达1天未打卡`);
                    }
                }

            }

            subject.diaryStats = diaryStats;
            subject.alerts = subject.alerts.concat(diaryStats.alerts);
            subject.warnings = subject.warnings.concat(diaryStats.warnings);
            subject.tips = subject.tips.concat(diaryStats.tips);

            const latestProfile = {};
            // 获取最新的备注记录
            const [[profile]] = await rds.query(
                `SELECT * FROM eb_user_profile WHERE type like '%_subject_${subject.id}_%' ORDER BY add_time DESC LIMIT 1`
            );
            if (profile) {
                latestProfile.created_time = moment(profile.add_time*1000).format("YYYY-MM-DD HH:mm:ss");
                const memo = JSON.parse(profile.memo);
                latestProfile.content = memo.content;
            }
            subject.latestProfile = latestProfile;

            // 获取物流补给信息
            const  latestSupplyInfo = {}
            if (subject.supply_info) {
                try {
                    // 尝试解析supply_info为JSON
                    const supplies = JSON.parse(subject.supply_info);

                    // 获取最新的补给信息
                    if (Array.isArray(supplies) && supplies.length > 0) {
                        Object.assign(latestSupplyInfo,supplies[supplies.length - 1]);
                    }
                } catch (error) {
                    console.error(`解析受试者${subject.id}的supply_info失败:`, error);
                }
            }

            const item = latestSupplyInfo.items ? latestSupplyInfo.items[0] : null;
            const item_info = item ? `${item.name}${item.quantity}${item.unit}` : '';

            latestSupplyInfo.item_info = item_info;
            subject.latestSupplyInfo = latestSupplyInfo;

            return subject;
        }));

        // 按状态分组
        const waitingForGroup = subjectsWithStats.filter(s => s.status === 2);
        const inGroup = subjectsWithStats.filter(s => s.status === 3);
        const registered = subjectsWithStats.filter(s => s.status === 1);
        const exited = subjectsWithStats.filter(s => s.status > 3);
        const watching = subjectsWithStats.filter(s => s.status === 0);

        // 按分组类型进一步分组（仅对已分组受试者）
        const groupedInGroup = [];
        const groupTypes = [...new Set(inGroup.map(s => s.group_type))];

        groupTypes.forEach(type => {
            const subjects = inGroup.filter(s => s.group_type === type);
            if (subjects.length > 0) {
                groupedInGroup.push({
                    type,
                    name: subjects[0].groupConfig.name || `分组 ${type}`,
                    subjects
                });
            }
        });

        // 计算统计数据
        const counts = {
            waitingForGroup: waitingForGroup.length,
            inGroup: inGroup.length,
            registered: registered.length,
            exited: exited.length,
            watching: watching.length,
            total: subjectsWithStats.length
        };

        // 构建响应数据
        const responseData = {
            trial,
            counts,
            groupedSubjects: {
                waitingForGroup,
                inGroup: groupedInGroup,
                registered,
                exited,
                watching
            }
        };

        res.render('trial/admin/dashboard', responseData);
    } catch (error) {
        console.error('获取看板数据失败:', error);
        res.status(500).send('服务器错误');
    }
});

// 获取受试者物流信息
router.get('/subjects/:subjectId/supplies', trialAuth, async (req, res) => {
    // ... existing code ...
});

// 获取受试者随访报告列表
router.get('/subjects/:subjectId/follow-ups', trialAuth, async (req, res) => {
    try {
        const { subjectId } = req.params;
        const { trial_id } = req.query;

        if (!subjectId) {
            return res.status(400).json({ success: false, message: '缺少必要参数' });
        }

        // 验证用户权限 - 放宽权限检查，允许任何已登录用户访问
        // if (!req.session.trialOps && !req.session.trialAdmin) {
        //     return res.status(403).json({ success: false, message: '无权访问' });
        // }

        // 获取受试者记录
        const [[subject]] = await rds.query(
            'SELECT * FROM trial_subjects WHERE id = ?',
            [subjectId]
        );

        if (!subject) {
            console.log(`[随访报告] 未找到受试者记录: subjectId=${subjectId}`);
            return res.status(404).json({ success: false, message: '未找到受试者记录' });
        }

        console.log(`[随访报告] 找到受试者记录: trial_id=${subject.trial_id}, user_id=${subject.user_id}, start_date=${subject.start_date}`);

        const startDate = subject?.start_date ? new Date(subject.start_date) : null;

        // 获取所有随访记录
        const [followups] = await rds.query(
            'SELECT * FROM trial_follow_up WHERE subject_id = ? ORDER BY created_at ASC',
            [subjectId]
        );

        console.log(`[随访报告] 找到随访记录: ${followups.length}条`);

        // 定义预期的随访天数（可以根据试验配置调整）
        const followUpDays = [13, 27, 43, 57, 73, 87]; // 可以从subject.follow_up_info中获取

        // 组织随访记录，按照targetDay分组
        const organizedFollowups = [];

        followups.forEach(followup => {
            // 解析JSON内容
            let content;
            try {
                content = JSON.parse(followup.content || '{}');
            } catch (e) {
                content = { targetDay: followup.day };
            }

            const targetDay = content.targetDay || followup.day;

            // 查找是否已经有该targetDay的记录
            const existingIndex = organizedFollowups.findIndex(f => f.targetDay === targetDay);

            if (existingIndex >= 0) {
                // 如果已有记录，且当前记录更新，则替换
                if (new Date(followup.created_at) > new Date(organizedFollowups[existingIndex].createdAt)) {
                    organizedFollowups[existingIndex] = {
                        id: followup.id,
                        day: followup.day,
                        targetDay: targetDay,
                        date: startDate ? new Date(startDate.getTime() + (followup.day - 1) * 24 * 60 * 60 * 1000) : null,
                        targetDate: startDate ? new Date(startDate.getTime() + (targetDay - 1) * 24 * 60 * 60 * 1000) : null,
                        content: content,
                        createdAt: followup.created_at,
                        updatedAt: followup.updated_at
                    };
                }
            } else {
                // 如果没有该targetDay的记录，则添加
                organizedFollowups.push({
                    id: followup.id,
                    day: followup.day,
                    targetDay: targetDay,
                    date: startDate ? new Date(startDate.getTime() + (followup.day - 1) * 24 * 60 * 60 * 1000) : null,
                    targetDate: startDate ? new Date(startDate.getTime() + (targetDay - 1) * 24 * 60 * 60 * 1000) : null,
                    content: content,
                    createdAt: followup.created_at,
                    updatedAt: followup.updated_at
                });
            }
        });

        res.json({
            success: true,
            subjectId,
            startDate,
            followups: organizedFollowups
        });
    } catch (error) {
        console.error('获取随访报告失败:', error);
        res.status(500).json({
            success: false,
            message: '获取随访报告失败',
            error: error.message
        });
    }
});

module.exports = router;
